浏览量 834
2024/03/28 14:42
AWS API GATEWAY 支持多个域名精准跨域
对于非简单请求添加跨域方法是增加OPTIONS方法,并MOCK 返回
对于这些集成,CORS 协议要求浏览器在发送实际请求之前向服务器发送一个预检请求,并等待来自服务器的批准(或对于凭证的请求)。您必须配置您的 API 以向预检请求发送适当的响应。
要创建预检响应,请执行以下操作:
使用模拟集成创建 OPTIONS 方法。
将以下响应标头添加到 200 方法响应中:
Access-Control-Allow-Headers
Access-Control-Allow-Methods
Access-Control-Allow-Origin
输入响应标头的值。要允许所有来源、所有方法和通用标头,请使用以下标头值:
Access-Control-Allow-Headers: 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'
Access-Control-Allow-Methods: '*'
Access-Control-Allow-Origin: '*'
创建预检请求后,对于至少所有 200 响应,必须为所有启用 CORS 的方法返回 Access-Control-Allow-Origin: '*' 或 Access-Control-Allow-Origin:'origin' 标头。
综上: aws 只支持通配符和单个精准域名跨域。
多个域名跨时的解决方法
报错
直接在MOCK集成响应添加
method.response.header.Access-Control-Allow-Origin:"https://web.qa.domain.cn, https://app.staging.domain.cn"
请求会发现,报错:
The 'Access-Control-Allow-Origin' header contains multiple values 'https://web.qa.domain.cn, https://app.staging.domain.cn', but only one is allowed.
两种解决方法
-
添加在mock方法后添加lambda 模拟返回允许的域名,此种方法会造成费用增加和性能损耗问题。
-
在OPTIONS方法中,集中响应内设置 Mapping templates,使用 Velocity Template 语言映射模板来检查允许的域列表并设置原始标头
#set($domains = ["https://web.qa.domain.cn", "https://app.staging.domain.cn"])
#set($origin = $input.params("Origin"))
#if($origin == "")
#set($origin = $input.params("origin"))
#end
#set($origin = $origin.replace(' ', '')))
#if($domains.contains($origin))
#set($context.responseOverride.header.Access-Control-Allow-Origin="$origin")
#set($context.responseOverride.header.Access-Control-Allow-Credentials = 'true')
#set($context.responseOverride.header.Access-Control-Allow-Headers = 'aaa,bbb,ccc,*')
#set($context.responseOverride.header.Access-Control-Allow-Methods = '*')
#set($context.responseOverride.header.Access-Control-Max-Age='1728000')
#end
此时预检查请求option方法时,此方法会根据 header中origin的域名去domains里检查是否存在,如果存在返回对应的 Access-Control-Allow-Origin header。
AWS API GATEWAY to support multiple domain names to accurately cross domains
Adding a cross-domain method for a non-simple request is to add the OPTIONS method and MOCK the return
For these integrations, the CORS protocol requires the browser to send a preflight request to the server and wait for approval (or a request for credentials) from the server before sending the actual request. You must configure your API to send an appropriate response to the preflight request.
To create a preflight response:
Create an OPTIONS method with a mock integration.
Add the following response headers to the 200 method response:
Access-Control-Allow-Headers
Access-Control-Allow-Methods
Access-Control-Allow-Origin
Enter values for the response headers. To allow all origins, all methods, and common headers, use the following header values:
Access-Control-Allow-Headers: 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'
Access-Control-Allow-Methods: '*'
Access-Control-Allow-Origin: '*'
After creating the preflight request, you must return the Access-Control-Allow-Origin: '*' or Access-Control-Allow-Origin:'origin' header for all CORS-enabled methods for at least all 200 responses.
To sum up: aws only supports wildcards and a single precise domain name cross-domain.
Solution for multiple domains across time
Error reported
Add responses directly in MOCK integration
method.response.header.Access-Control-Allow-Origin:"https://web.qa.domain.cn, https://app.staging.domain.cn"
Request found, error reported:
The 'Access-Control-Allow-Origin' header contains multiple values 'https://web.qa.domain.cn, https://app.staging.domain.cn', but only one is allowed.
Two solutions
-
Add lambda simulation to return the allowed domain name after the mock method, which will cause cost increase and performance loss.
-
In the OPTIONS method, set Mapping templates in the centralized response, use the Velocity Template language mapping template to check the list of allowed fields and set the original header.
#set($domains = ["https://web.qa.domain.cn", "https://app.staging.domain.cn"])
#set($origin = $input.params("Origin"))
#if($origin == "")
#set($origin = $input.params("origin"))
#end
#set($origin = $origin.replace(' ', '')))
#if($domains.contains($origin))
#set($context.responseOverride.header.Access-Control-Allow-Origin="$origin")
#set($context.responseOverride.header.Access-Control-Allow-Credentials = 'true')
#set($context.responseOverride.header.Access-Control-Allow-Headers = 'aaa,bbb,ccc,*')
#set($context.responseOverride.header.Access-Control-Allow-Methods = '*')
#set($context.responseOverride.header.Access-Control-Max-Age='1728000')
#end
At this time, when the request option method is pre-checked, this method will go to the domains according to the origin domain name in the header to check whether they exist, and return the corresponding Access-Control-Allow-Origin header if they exist.
上一篇 搜索 下一篇